package controller
{
	import assets.Assets;
	
	import avmplus.USE_ITRAITS;
	
	import event.GameEvent;
	
	import flash.data.SQLConnection;
	import flash.data.SQLStatement;
	import flash.desktop.NativeApplication;
	import flash.desktop.SystemIdleMode;
	import flash.display.DisplayObject;
	import flash.display.NativeMenu;
	import flash.display.NativeWindow;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.SampleDataEvent;
	import flash.events.TimerEvent;
	import flash.filesystem.File;
	import flash.media.Sound;
	import flash.system.Capabilities;
	import flash.ui.Keyboard;
	import flash.utils.ByteArray;
	import flash.utils.Timer;
	
	import model.Jogador;
	import model.ModelLocator;
	
	import mx.collections.ArrayCollection;
	import mx.core.FlexGlobals;
	import mx.core.IFlexDisplayObject;
	import mx.events.FlexEvent;
	import mx.managers.ISystemManager;
	import mx.managers.PopUpManager;
	import mx.managers.PopUpManagerChildList;
	import mx.messaging.ChannelSet;
	import mx.messaging.Consumer;
	import mx.messaging.channels.AMFChannel;
	import mx.messaging.channels.RTMPChannel;
	import mx.messaging.events.MessageEvent;
	import mx.messaging.messages.AsyncMessage;
	import mx.messaging.messages.IMessage;
	import mx.rpc.AsyncToken;
	import mx.rpc.Responder;
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;
	import mx.rpc.remoting.mxml.RemoteObject;
	
	import org.osmf.events.TimeEvent;
	
	import spark.components.Application;
	import spark.components.PopUpAnchor;
	import spark.components.PopUpPosition;
	import spark.components.View;
	import spark.components.ViewNavigator;
	
	import views.Alert;
	import views.MenuTab;
	import views.Mesas;
	import views.MsgBox;
	import views.PopUpTruco;
	import views.trucoHome;

	public class GameController
	{
		private var modelLocator:ModelLocator=ModelLocator.getInstance();
		private var popUpTruco:PopUpTruco;
		private var alert:Alert;
		private var msgBoxBack:MsgBox;
		
		public function addEventListersHandler():void
		{
			timerTruco();
			if(Capabilities.cpuArchitecture=="ARM")
			{
				NativeApplication.nativeApplication.addEventListener(Event.ACTIVATE, handleActivate, false, 0, true);
				NativeApplication.nativeApplication.addEventListener(Event.DEACTIVATE, handleDeactivate, false, 0, true);
				NativeApplication.nativeApplication.addEventListener(KeyboardEvent.KEY_DOWN, handleKeys, false, 0, true);
			}
			modelLocator.consumer.addEventListener(MessageEvent.MESSAGE,messageHandler);
			modelLocator.consumerChat.addEventListener(MessageEvent.MESSAGE,messageHandlerChat);
			creationCompleteHandler();
		}
		
		private function handleActivate(event:Event):void
		{
			NativeApplication.nativeApplication.systemIdleMode = SystemIdleMode.KEEP_AWAKE;
		}
		
		private function handleDeactivate(event:Event):void
		{
			//NativeApplication.nativeApplication.exit();
		}
		
		private function handleKeys(keyEvent:KeyboardEvent):void
		{
			if(keyEvent.keyCode == Keyboard.BACK) // 16777238
			{
				if(modelLocator.numeroView==2)
				{
					modelLocator.numeroView=1;
				}
				else
				{
					if(modelLocator.numeroView==0)
					{
						NativeApplication.nativeApplication.exit();	
					}
					else if(modelLocator.numeroView==1)
					{
						modelLocator.habilitaMesa=false;
						modelLocator.gameEvent.dispatchEvent(new Event(GameEvent.STOP_TIMER));
						modelLocator.ro.removeMesaWait(modelLocator.mesa);
					}
				}
			}
			else if(keyEvent.keyCode == Keyboard.MENU)//16777234
			{
				if(modelLocator.numeroView==1)
				{
					modelLocator.gameEvent.dispatchEvent(new Event(GameEvent.MENU_PRESSED));
				}
			}
		}
		
		
		public function createMesaHandler(idMesa:int=0):void
		{
			var idUser:int;
			var rand:Number = Math.random();
			idUser = Math.round(rand * 9999);
			modelLocator.idUser=idUser;
			var call:AsyncToken=modelLocator.ro.createMesa(idUser,idMesa,modelLocator.jogador);
			call.addResponder(new Responder(createMesaResult,fault));
		}
		
		public function enviaJogadaHandler(carta:String):void
		{
			var call:AsyncToken=modelLocator.ro.jogada(carta,modelLocator.mesa,modelLocator.idUser);
			//call.addResponder(new Responder(createMesaResult,fault));
		}
		
		private function createMesaResult(resultEvent:ResultEvent):void
		{
			modelLocator.jogador=resultEvent.result as Jogador;
			modelLocator.mesa=modelLocator.jogador.numeroMesa;
			modelLocator.gameEvent.dispatchEvent(new Event(GameEvent.CREATE_MESA_RESULT));
		}
		
		private function messageHandler(msg:MessageEvent):void
		{
			var message:IMessage=msg.message;
			if(message.body.mesa==modelLocator.mesa)
			{
				modelLocator.rodada=message.body.rodada;
				if(message.body.rodada==0)
				{
					iniciaMesa(message.body);
				}
				else
				{
					fazJogada(message.body);
				}
			}
		}
		private function messageHandlerChat(msg:MessageEvent):void
		{
			var message:IMessage=msg.message;
			if(message.body.mesa==modelLocator.mesa)
			{
				var sm:ISystemManager = ISystemManager(FlexGlobals.topLevelApplication.systemManager);
				var parent:Sprite = Sprite(sm.getSandboxRoot());
				if(message.body.type=="chat")
				{
					modelLocator.gameEvent.dispatchEvent(new ResultEvent(GameEvent.RECIVE_MSG,false,true,message.body));	
				}
				else if(message.body.type=="truco")
				{
					if(modelLocator.valorRodada<10 && (modelLocator.pAdver!=11 && modelLocator.pVoce!=11))
					{
						
						modelLocator.userTrucada=message.body.userTrucada;
						if(message.body.userTrucada!=modelLocator.idUser)
						{
							modelLocator.userNaoTrucando=true;
							popUpTruco=new PopUpTruco();
							PopUpManager.addPopUp(popUpTruco,parent,false);
							PopUpManager.centerPopUp(popUpTruco);	
						}
						else
						{
							modelLocator.userNaoTrucando=false;
							modelLocator.statusTruco="Aguardando o adversário";
							alert=new Alert();
							PopUpManager.addPopUp(alert,parent,false);
							PopUpManager.centerPopUp(alert);
						}
					}
					else
					{
						modelLocator.userNaoTrucando=false;
					}
				}
				else if(message.body.type=="aceita")
				{
					modelLocator.statusTruco="O adversário aceitou";
					aceitaTrucoHandler();
					tAlert.reset();
					tAlert.start();
					labelProximoValor();
				}
				else if(message.body.type=="corre")
				{
					modelLocator.statusTruco="O adversário correu";
					var obj:Object=new Object();
					obj.venceuRodada=modelLocator.userTrucada;
					setVencedor(obj);
					modelLocator.gameEvent.dispatchEvent(new Event(GameEvent.CORRE));
					tAlert.reset();
					tAlert.start();
				}
				else if(message.body.type=="dobra")
				{
					aceitaTrucoHandler();
					closeAlert();
					modelLocator.userTrucada=message.body.userTrucada;
					labelProximoValor();
					if(modelLocator.userTrucada==modelLocator.idUser)
					{
						var msgn:IMessage = new AsyncMessage();
						msgn.body.type="truco";
						msgn.body.vrlRodada = modelLocator.valorRodada;
						msgn.body.mesa=modelLocator.mesa;
						msgn.body.userTrucada=modelLocator.userTrucada;
						modelLocator.producer.send(msgn);
					}
				}
				else if(message.body.type=="abandonouMesa")
				{
					if(modelLocator.numeroView==1)
					{
						msgBoxBack=new MsgBox()
						msgBoxBack.menssagem="Houve um abandono do jogo";
						msgBoxBack.addEventListener("ClickOkEvent",goBackView)
						PopUpManager.addPopUp(msgBoxBack,parent,false);
						PopUpManager.centerPopUp(msgBoxBack);	
					}
					
				}
			}
			if(message.body.type=="updateMesas")
			{
				modelLocator.mesasAguardando=message.body.listMesasWait;
			}
		}
		
		private function goBackView(events:Event):void
		{
			msgBoxBack.removeEventListener("ClickOkEvent",goBackView);
			modelLocator.gameEvent.dispatchEvent(new Event(GameEvent.GO_BACK))
		}
		
		private function aceitaTrucoHandler():void
		{
			if(modelLocator.valorRodada==1)
			{
				modelLocator.valorRodada=3;
			}
			else
			{
				modelLocator.valorRodada+=3;
			}
		}
		
		public function labelProximoValor():void
		{
			if(modelLocator.valorRodada==1)
			{
				modelLocator.labelNextRodada="Truco";
			}
			else
			{
				modelLocator.labelNextRodada=String(modelLocator.valorRodada+3);
				if((modelLocator.valorRodada+3)>12)
				{
					modelLocator.userNaoTrucando=false;
				}
			}
		}
		
		private function closeAlert(event:Event=null):void
		{
			if(alert!=null)
			{
				PopUpManager.removePopUp(alert);
				alert=null;
			}
		}
		
		public function getVira():void
		{
			var call:AsyncToken=modelLocator.ro.getVira(modelLocator.mesa);
			call.addResponder(new Responder(getViraHandler,fault));
		}
		private function getViraHandler(resultEvent:ResultEvent):void
		{
			modelLocator.vira=resultEvent.result.vira;
			modelLocator.gameEvent.dispatchEvent(new Event(GameEvent.SET_VIRA));
		}
		private function iniciaMesa(obj:Object):void
		{
			if(obj.jogador1.id!=modelLocator.idUser)
			{
				modelLocator.oponente=obj.jogador1;
			}
			else
			{
				modelLocator.oponente=obj.jogador2;
			}
			modelLocator.vira=obj.vira;
			modelLocator.gameEvent.dispatchEvent(new Event(GameEvent.SET_VIRA));
			verificaUsuarioVez(obj.usuarioVez);
		}
		
		private function fazJogada(obj:Object):void
		{
			modelLocator.gameEvent.dispatchEvent(new ResultEvent(GameEvent.SET_CARTA,false,true,obj));
			if(obj.venceuRodada!=0)
			{
				setVencedor(obj);
			}
			else
			{
				verificaUsuarioVez(obj.usuarioVez);				
			}
		}
		
		private function setVencedor(obj:Object):void{
			
			var sm:ISystemManager = ISystemManager(FlexGlobals.topLevelApplication.systemManager);
			var parent:Sprite = Sprite(sm.getSandboxRoot());
			var msgBox:MsgBox;
			if(obj.venceuRodada==modelLocator.idUser)
			{
				modelLocator.pVoce+=modelLocator.valorRodada;
				if(modelLocator.pVoce>=12)
				{
					modelLocator.pVoce=12;
					//vc venceu
					modelLocator.jogador.vitorias+=1;
					modelLocator.jogador.partidas+=1;
					msgBox=new MsgBox()
					msgBox.menssagem="Você venceu parabéns";
					PopUpManager.addPopUp(msgBox,parent,false);
					PopUpManager.centerPopUp(msgBox);
					modelLocator.pVoce=0;
					modelLocator.pAdver=0;
					//
				}
			}
			else
			{
				modelLocator.pAdver+=modelLocator.valorRodada;
				if(modelLocator.pAdver>=12)
				{
					modelLocator.pAdver=12;
					//vc perdeu
					modelLocator.jogador.derrotas+=1;
					modelLocator.jogador.partidas+=1;
					msgBox=new MsgBox()
					msgBox.menssagem="Você perdeu";
					PopUpManager.addPopUp(msgBox,parent,false);
					PopUpManager.centerPopUp(msgBox);
					modelLocator.pVoce=0;
					modelLocator.pAdver=0;
					//
				}
			}
			saveDadosPartida();
			t.reset();
			t.start();
		}
		
		private function restartMesa(timeEvent:Event):void
		{
			modelLocator.gameEvent.dispatchEvent(new Event(GameEvent.RESET));
			modelLocator.habilitaMesa=false;
		}
		
		private function verificaUsuarioVez(idUserVez:int):void
		{
				if(idUserVez==modelLocator.idUser)
				{
					modelLocator.usuarioVez=modelLocator.jogador.nome==""||modelLocator.jogador.nome==null?"Você":modelLocator.jogador.nome;
					modelLocator.usuarioVezAvatar=modelLocator.jogador.avatar==null?Assets.userDefault:Assets[modelLocator.jogador.avatar];
					modelLocator.habilitaMesa=true;
				}
				else{
					modelLocator.usuarioVez=modelLocator.oponente.nome==""||modelLocator.oponente.nome==null?"Oponente":modelLocator.oponente.nome;;
					modelLocator.usuarioVezAvatar=modelLocator.oponente.avatar==null?Assets.userDefault:Assets[modelLocator.oponente.avatar];
					modelLocator.habilitaMesa=false;
				}
				modelLocator.idUsuarioVez=idUserVez;
		}
		
		public function trocaMao():void
		{
			var call:AsyncToken=modelLocator.ro.changeHand(modelLocator.mesa,modelLocator.idUser);
			call.addResponder(new Responder(createMesaResult,fault));
			if(modelLocator.idUsuarioVez==modelLocator.idUser)
			{
				resetTable();
			}
		}
		
		public function resetTable():void
		{
			modelLocator.ro.resetTable(modelLocator.mesa,modelLocator.inicia);
		}
		
		///////////////////////////////////////////
		public function getMesasWait():void
		{
			var call:AsyncToken=modelLocator.ro.getMesasWait();
			call.addResponder(new Responder(getMesasWaitHandler,fault));
		}
		private function getMesasWaitHandler(resultEvent:ResultEvent):void
		{
			modelLocator.mesasAguardando=resultEvent.result as ArrayCollection;
		}
		///////////////////////////////////////////
		
		
		//timer para ver a ultima carta da rodada
		private var t:Timer;
		private var tAlert:Timer;
		private const TIMER_INTERVAL:int = 1000;
		private function timerTruco():void
		{
			t = new Timer(TIMER_INTERVAL,2);
			t.addEventListener(TimerEvent.TIMER_COMPLETE,restartMesa);
			tAlert = new Timer(TIMER_INTERVAL,2);
			tAlert.addEventListener(TimerEvent.TIMER_COMPLETE,closeAlert);
		}
		
		////sql
			
		private function creationCompleteHandler():void
		{
			modelLocator.sqlConnection = new SQLConnection();
			modelLocator.sqlConnection.open(File.applicationStorageDirectory.resolvePath("truco.db"));
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = modelLocator.sqlConnection;
			//stmt.text="DROP TABLE truco";
			stmt.text = "CREATE TABLE IF NOT EXISTS truco (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, vitorias INTEGER, derrotas INTEGER, partidas INTEGER, nome TEXT, mesa TEXT, avatar TEXT)";
			stmt.execute();
			//getAllJogador();
		}
		
		public function getAllJogador():void
		{
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = modelLocator.sqlConnection;
			stmt.text = "SELECT id, nome, mesa, avatar, vitorias, derrotas, partidas FROM truco";
			stmt.execute();
			var obj:Object = stmt.getResult().data;
			modelLocator.jogador=new Jogador();
			if(obj)
			{
				modelLocator.jogador.idSql=obj[0].id;
				modelLocator.jogador.nome=obj[0].nome;
				modelLocator.jogador.mesa=obj[0].mesa;
				modelLocator.jogador.avatar=obj[0].avatar;
				modelLocator.jogador.vitorias=obj[0].vitorias;
				modelLocator.jogador.derrotas=obj[0].derrotas;
				modelLocator.jogador.partidas=obj[0].partidas;
				//avatarSelected.source=Assets[jogador[0].avatar];
				
			}
		}
		
		protected function saveDadosPartida():void
		{
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = modelLocator.sqlConnection;
			if(modelLocator.jogador.idSql==-1)
			{
				stmt.text = "INSERT into truco(vitorias, derrotas, partidas, nome, mesa, avatar) values(:vitorias, :derrotas, :partidas, :nome, :mesa, :avatar)";
				stmt.parameters[":vitorias"] = modelLocator.jogador.vitorias;
				stmt.parameters[":derrotas"] = modelLocator.jogador.derrotas;
				stmt.parameters[":partidas"] = modelLocator.jogador.partidas;
				stmt.parameters[":nome"] = "";
				stmt.parameters[":mesa"] = "";
				stmt.parameters[":avatar"] = "userDefault";
			}
			else
			{
				stmt.text = 'UPDATE truco set vitorias="'+modelLocator.jogador.vitorias+'", derrotas="'+modelLocator.jogador.derrotas+'", partidas="'+modelLocator.jogador.partidas+'" where id="'+modelLocator.jogador.idSql+'"';
			}
			stmt.execute();
		}
		
		
		
		private function fault(faultEvent:FaultEvent):void
		{
			trace(faultEvent.fault.faultDetail);
		}
	}
}